﻿using GalaSoft.MvvmLight;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VisionApp.Interface;
using VisionApp.NetService;
using VisionApp.Entity;
using GalaSoft.MvvmLight.Messaging;

namespace VisionAppManager.Model
{
    public class RobotModel:ModelBase
    {
        private Logger _log;
        private CfgIO _cfg;
        private SuperSocketServer _server = new SuperSocketServer();
        private VSResultContainer _rc = null;
        private RobCfgData _cfgData;
        public RobCfgData CfgData
        {
            get
            {
                return _cfgData;
            }
            set
            {
                Set<RobCfgData>(ref _cfgData, value);
            }
        }
        public string Result { get; set; }
        public RobotModel(ILogger log, ICfgIO cfg)
        {
            _log = (Logger)log;
            _cfg=(CfgIO)cfg;
            _cfgData = new RobCfgData();
            _cfg.Load("RobCfgData", ref _cfgData);
            if (_cfgData == null)
            {
                _cfgData = new RobCfgData();
                _cfg.Save("RobCfgData", _cfgData);
            }
        }

        public int Init()
        {
            try
            {
                _server.BuildServer(_cfgData.LocalIP, _cfgData.Port);
                _log.Imformation(string.Format("Server open at{0}:{1}", _cfgData.LocalIP, _cfgData.Port));
                Messenger.Default.Register<RobotStatus>(this, (rs) => robStatusUpdate(rs));
                return 0;
            }catch(Exception e)
            {
                _log.Error("Robot init error " + e.ToString());
                return -1;
            }
        }

        private void robStatusUpdate(RobotStatus rs)
        {
            switch (rs)
            {
                case RobotStatus.CONNECTED:
                    Connected = true;
                    break;
                case RobotStatus.DISCONNECT:
                    Connected = false;
                    break;
                default:
                    break;
            }
        }

        public void SetVSResCtnr(string offset)
        {
            Result = offset;
        }

        public int SendResult(string type)
        {
            switch (type)
            {
                case "OK":
                    OK();
                    break;
                case "ack":
                    ack();
                    break;
                case "error":
                    error();
                    break;
                case "OutRange":
                    outrange();
                    break;
                default:
                    break;
            }
            return 0;
        }

        public void SaveCfg()
        {
            _cfg.Save<RobCfgData>("RobCfgData", CfgData);
        }

        public int Close()
        {
            _server.StopServer();
            _log.Imformation(string.Format("Server closed"));
            return 0;
        }

        private int OK()
        {
            try
            {
                _server.SendMessage(_cfgData.LocalIP, "OK");
                _log.Imformation("Result sent to robot "+ "OK");
                return 0;
            }
            catch (Exception e)
            {
                _log.Error("SendResult Error" + e.ToString());
                return -1;
            }
        }

        private int ack()
        {
            try
            {
                _server.SendMessage(_cfgData.LocalIP, "1");
                _log.Imformation("ACK sent to robot");
                return 0;
            }
            catch (Exception e)
            {
                _log.Error("ACK Error" + e.ToString());
                return -1;
            }
        }

        private int error()
        {
            try
            {
                _server.SendMessage(_cfgData.LocalIP, "0");
                _log.Imformation("error sent to robot");
                return 0;
            }
            catch (Exception e)
            {
                _log.Error("Error SendMessage" + e.ToString());
                return -1;
            }
        }

        private int outrange()
        {
            try
            {
                _server.SendMessage(_cfgData.LocalIP, "0");
                return 0;
            }
            catch (Exception e)
            {
                _log.Error("Error SendMessage" + e.ToString());
                return -1;
            }
        }
    }
    public class RobCfgData : ObservableObject
    {
        private string _localIP = "192.168.125.1";
        public string LocalIP
        {
            get
            {
                return _localIP;
            }
            set
            {
                Set<string>(ref _localIP, value);
            }
        }

        private int _port = 3000;
        public int Port
        {
            get
            {
                return _port;
            }
            set
            {
                Set<int>(ref _port, value);
            }
        }
    }
}
